//
// Created by wopy on 2020/9/2.
//

#ifndef FCITX_FCITXBIHUAINPUTMETHOD_TABLE_HPP
#define FCITX_FCITXBIHUAINPUTMETHOD_TABLE_HPP
#include "config.h"

#include <string>
#include <vector>
#include <json/json.h>

using namespace std;
using namespace Json;


enum TABLETYPE {
    TABLE_TYPE_CORE,    //键位表
    TABLE_TYPE_THESAURUS,    //扩展词典
    TABLE_ERROR
};

typedef vector<FcitxCandidateWord> SortList;

class Table {
private:
    string path;    //词汇文件路径
    Value root;     //词汇数据表
    TABLETYPE type; //词表类型
    static void *context;   //InputState实例

    /***
     * 获取词表中最大的字符串的长度
     * @param sortList  候选词表
     * @return  最大长度
     */
    static int maxLen(const SortList & sortList);
    /***
     * 排列指定长度的词汇，并输出到fcitx候选词表
     * @param wordList   词表
     * @param dstList   fcitx候选词表
     * @param len   要排序的词汇的长度
     */
    static void sortForLen(SortList & wordList,FcitxCandidateWordList * dstList, const int len);
    /***
     * 从传入词汇生成Fcitx候选词
     * @param value 传入词汇
     * @param pSize 前缀长度
     * @param dstWord   取出候选词
     * @return  正常返回Fcitx候选词，出错返回空指针
     */
    static FcitxCandidateWord *make(Value &value, int pSize
                                         , FcitxCandidateWord *dstWord);
public:
    /***
     * Table构造函数，从json文件构造Table
     * @param path  json格式的词汇表
     * @param type  词汇表类型
     */
    explicit Table(string path, TABLETYPE type = TABLE_TYPE_THESAURUS);
    /***
     * Table构析函数
     */
    ~Table();
    /***
     * 保存Table到json文件
     */
    void save();
    /***
     * 从键码获得Fcitx候选词表
     * @param keyCode   键码
     * @param dstList   Fcitx候选词表
     * @param callback  回调函数
     * @return  符合条件的数量
     */
    int getWordListForKeyCode(const char *keyCode, FcitxCandidateWordList * dstList
                               , FcitxCandidateWordCommitCallback callback);
    /***
     * 从前缀获得Fcitx候选词表
     * @param prefix    前缀
     * @param dstList   Fcitx候选词表
     * @param callback  回调函数
     * @return  符合条件的数量
     */
    int getWordListForPrefix(const char *prefix, FcitxCandidateWordList *dstList
                              , FcitxCandidateWordCommitCallback callback);
    /*!
     * 更新词汇使用频率
     * @param word 要更新的词汇
     */
    void updateFreq(const char *word);
    /***
     * 排列词汇表，并输出到Fcitx候选词表
     * @param srcList   要排序的词汇表
     * @param dstList   Fcitx候选词表
     */
    void sort(SortList & srcList, FcitxCandidateWordList * dstList);
    /***
     * 设置上下文
     * @param context   InputState实例
     */
    static void setContext(void *context);
};

/***
 * 排列候选词时用到的比较函数
 * @param w1    候选词1
 * @param w2    候选词2
 * @return  比较结果
 */
extern bool operator<(const FcitxCandidateWord &w1, const FcitxCandidateWord &w2);

#endif //FCITX_FCITXBIHUAINPUTMETHOD_TABLE_HPP
